<template>
  <div class="tab-blue">
    <div class="tab-blue__wrapper flex-center">
      <div
        class="tab-blue__nav justify-content-center"
        ref="nav"
      >
        <div
          class="tab-blue__nav__prev"
          v-show="listScrollLeft > 30"
          @click="scrollBtnHandller('prev')"
        ></div>
        <ul
          class="tab-blue__list px-4"
          ref="list"
          @scroll="listOnScroll"
        >
          <li
            v-for="(tab, idx) in tabList"
            :key="tab.key"
            class="tab-blue__list__item"
            :ref="(el: HTMLElement) => (tabItem[idx] = el as HTMLElement)"
          >
            <button
              type="button"
              class="tab-blue__btn"
              :class="{ 'tab-blue__btn--active': activeIdx == idx }"
              :ref="(el: HTMLElement) => (tabBtn[idx] = el as HTMLElement)"
              @click="activeIdx = idx"
            >
              {{ tab.name }}
            </button>
          </li>
          <span
            class="tab-blue__strip"
            :style="`--strip-width:${stripWidth}px;--strip-left:${stripLeft}px;--list-scroll-left:${listScrollLeft}px;--fix-left:${navLeftPosFix}px`"
          ></span>
        </ul>
        <div
          class="tab-blue__nav__next"
          v-show="isLastChild"
          @click="scrollBtnHandller('next')"
        ></div>
      </div>

      <div
        v-if="sort && filter"
        class="tab-blue__filter zIndex2 mt-5 mt-md-3"
        :style="{ '--width': `${listWidth}px` }"
      >
        <div class="tab-blue__filter__sort" v-if="sort.length > 0">
          <ListSort
            :list="sort"
            :focusKey="sortAns"
            @updateKey="sortAns = $event"
          />
        </div>
        <div class="tab-blue__filter__filter" v-if="filter.length > 0">
          <ListFilter
            :list="filter"
            :focusKey="filterAns"
            @updateKey="filterAns = $event"
          />
        </div>
      </div>

      <div
        v-if="year.length > 0"
        class="tab-blue__filter mt-5 mt-md-3"
        :style="{ '--width': `${listWidth}px` }"
      >
        <div class="tab-blue__filter__filter" v-if="year.length > 1">
          <ListSort
            :list="year"
            :year="true"
            :focusKey="filterYears"
            @updateKey="filterYears = $event"
          />
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue'
import ListSort from './ListSort.vue'
import ListFilter from './ListFilter.vue'

// 定义组件名称
defineOptions({
  name: 'TabBlue'
})

// 定义 props
interface ComponentProps {
  classes?: string
  style?: Record<string, any>
  list?: any[]
  center?: boolean
  sort?: any[]
  filter?: any[]
}

const props = defineProps<{
  componentProps?: ComponentProps
  currentIdx?: number
  keySort?: string | number | null | undefined
  keyFilter?: any[]
  yearList?: any[]
  keyYear?: string | number | null
  articleTabList?: any[]
}>()

// 定义 emits
const emit = defineEmits<{
  updateIdx: [value: number]
  updateSort: [value: string | number | null | undefined]
  updateFilter: [value: any[]]
  updateYear: [value: string | number]
}>()

// 模板引用
const nav = ref<HTMLElement | null>(null)
const list = ref<HTMLElement | null>(null)
const tabItem = ref<HTMLElement[]>([])
const tabBtn = ref<HTMLElement[]>([])

// 响应式数据
const stripRight = ref(0)
const stripLeft = ref(0)
const listScrollLeft = ref(0)
const lastChildRight = ref(0)
const navLeftPosFix = ref(0)
const dirRight = ref(true)
const listWidth = ref(300)
const currentTabPos = ref(0)

const tabList = computed(() => {
  if (Array.isArray(props.articleTabList)) {
    return props.articleTabList
  }
  return props.componentProps?.list ?? null
})

const sort = computed(() => {
  return props.componentProps?.sort ?? null
})

const filter = computed(() => {
  return props.componentProps?.filter ?? []
})

const year = computed(() => {
  const getAllyear = props.yearList ?? []
  const yearLangs = '所有年份'
  const newTest = [...getAllyear]
  newTest.unshift(yearLangs)
  return props.yearList ? newTest : []
})
const sortAns = computed({
  get() {
    return props.keySort
  },
  set(newValue: string | number | null | undefined) {
    emit('updateSort', newValue)
  }
})

const filterAns = computed({
  get() {
    return props.keyFilter
  },
  set(newValue: any[]) {
    emit('updateFilter', newValue)
  }
})

const filterYears = computed({
  get() {
    return props.keyYear
  },
  set(newValue: string | number) {
    emit('updateYear', newValue)
  }
})

const activeIdx = computed({
  get() {
    return props.currentIdx ?? 0
  },
  set(newValue: number) {
    emit('updateIdx', newValue)
    nextTick(() => centerTheList())
  }
})

const stripWidth = computed(() => {
  return stripRight.value - stripLeft.value
})

const isLastChild = computed(() => {
  if (typeof window === 'undefined') return false
  return lastChildRight.value - window.innerWidth > 20
})

// 窗口宽度响应式变量
const windowWidth = ref(typeof window !== 'undefined' ? window.innerWidth : 0)

// 监听器
watch(() => props.currentIdx, (newValue: number, oldValue: number) => {
  dirRight.value = (newValue ?? 0) > (oldValue ?? 0)
  nextTick(() => calStrip())
})

watch(windowWidth, () => {
  calListScrollLeft()
  calStrip()
})
// 方法
const calNavLeftPos = () => {
  const target = nav.value
  if (target) {
    navLeftPosFix.value = target.getBoundingClientRect().left
  }
}

const calStripRight = () => {
  const target = tabBtn.value[activeIdx.value]
  if (target) {
    stripRight.value = target.getBoundingClientRect().right
  }
}

const calStripLeft = () => {
  const target = tabBtn.value[activeIdx.value]
  if (target) {
    stripLeft.value = target.getBoundingClientRect().left
  }
}

setTimeout(() => {
  console.log('stripLeft=======', tabBtn.value[5].getBoundingClientRect().left)
}, 500)

const calStrip = (delay = 250) => {
  if (dirRight.value) {
    calStripRight()
    setTimeout(calStripLeft, delay)
  } else {
    calStripLeft()
    setTimeout(calStripRight, delay)
  }
  updateListWidth()
}

const calListScrollLeft = () => {
  const listEl = list.value
  if (listEl) {
    listScrollLeft.value = listEl.scrollLeft
  }
  calNavLeftPos()
  nextTick(() => calStrip(50))
  nextTick(calLastChild)
}

const calLastChild = () => {
  const listItems = tabItem.value
  if (listItems && listItems.length > 0) {
    const target = listItems[listItems.length - 1]
    if (target) {
      lastChildRight.value = target.getBoundingClientRect().right
    }
  }
}

const listOnScroll = () => {
  calListScrollLeft()
}

const scrollBtnHandller = (dir: string) => {
  const listEl = list.value
  if (!listEl) return

  if (dir === 'next') {
    listEl.scrollLeft = listScrollLeft.value + 100
  } else {
    listEl.scrollLeft = listScrollLeft.value - 100
  }
}

const updateListWidth = () => {
  const listEl = list.value
  if (listEl) {
    listWidth.value = listEl.clientWidth
  }
}

const centerTheList = () => {
  if (typeof window === 'undefined') return

  const currentTab = tabBtn.value[activeIdx.value]
  if (!currentTab) return

  const tabHalfWidth = currentTab.clientWidth / 2
  const center = window.innerWidth / 2
  currentTabPos.value = currentTab.getBoundingClientRect().right - tabHalfWidth

  const listEl = list.value
  if (listEl) {
    listEl.scrollLeft -= center - currentTabPos.value
  }
}
// 生命周期
onMounted(() => {
  nextTick(() => {
    setTimeout(listOnScroll, 300)
  })

  // 监听窗口大小变化（仅客户端）
  if (typeof window !== 'undefined') {
    const handleResize = () => {
      windowWidth.value = window.innerWidth
    }
    window.addEventListener('resize', handleResize)

    onBeforeUnmount(() => {
      window.removeEventListener('resize', handleResize)
    })
  }
})
</script>

<style lang="scss" scoped>
.tab-blue {
  &__wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  &__nav {
    display: flex;
    align-items: center;
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    position: relative;
    z-index: 1;
    min-height: 38px;
    overflow: hidden;

    &__prev,
    &__next {
      position: absolute;
      width: 25px;
      height: 38px;
      box-shadow: 0px 4px 4px rgba(255, 255, 255, 0.2);
      background-color: #F7F7FA;
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 1;
      
      &::after {
        content: '';
        width: 24px;
        height: 38px;
        background-image: url();
        background-size: 24px 38px;
      }       
    }
        
    &__prev {
      left: -1px;
      &::after {
        transform: scale(-1);
      }
    }
        
    &__next {
      right: -1px;
    }   
  }

  &__list {
    display: flex;
    align-items: center;
    overflow-x: auto;
    scroll-behavior: smooth;
    scrollbar-width: none;
    -ms-overflow-style: none;
    padding: 0 16px;
    list-style: none;
    margin: 0;

    &::-webkit-scrollbar {
      display: none;
    }

    &__item {
      flex-shrink: 0;
      margin-right: 4px;

      @media (max-width: 1023.98px) {
        margin-right: 0;
      }

      @media (max-width: 767.98px) {
        margin-right: 6px;
      }

      &:first-of-type {
        margin-left: 0;
      }

      &:last-of-type {
        margin-right: 0;
      }
    }
  }

  &__btn {
    width: auto;
    border: none;
    background: none;
    font-size: 16px;
    font-weight: 500;
    line-height: 1.5;
    white-space: nowrap;
    padding: 8px 20px;
    color: $gray-700;
    text-decoration: none;
    cursor: pointer;
    transition: color 0.3s ease-in-out;

    @media (max-width: 767.98px) {
      padding: 4px 10px;
      font-size: 14px;
    }

    &:hover {
      color: $primary-600;

      &.tab-blue__btn--active {
        color: $gray-50;
      }
    }

    &--active {
      color: $gray-50;
    }
  }

  &__strip {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    left: calc(var(--strip-left, 0px) - var(--fix-left, 0px));
    width: var(--strip-width, 0px);
    height: 100%;
    background: var(--tab-strip-color, #0032a0);
    transition: left 0.2s ease-in-out, width 0.2s ease-in-out;
    z-index: -1;
    border-radius: 3px;
    overflow: hidden;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

    @media (max-width: 767.98px) {
      max-height: 26px;
    }
  }
}

.tab-blue__filter {
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 1200px;
  margin: 0 auto;
  width: 100%;
  width: var(--width,100%);
  position: relative;
  z-index: 1;
}

.tab-blue__filter__filter,.tab-blue__filter__sort {
  width: 50%;
}

.tab-blue__filter__filter:only-child,.tab-blue__filter__sort:only-child {
  width: 100%;
}

.tab-blue__filter__filter:last-child,.tab-blue__filter__sort:last-child {
  margin-right: 8px;
}

@media(max-width: 767.98px) {
  .tab-blue__nav__next,.tab-blue__nav__prev {
    box-shadow:0 0 8px rgba(0,0,0,.22);
  }
}

@media(max-width: 1023.98px) {
  .tab-blue__nav__next:after,.tab-blue__nav__prev:after {
    width: 14px;
    height: 14px;
    background-size: 14px 14px;
  }
}
</style>
